#pragma once

#include "IXMsgListenSrv.h"
#include "XBaseObjImpl.h"
#include "TimerUtil.h"

struct ListenerInfo
{
    XWND               xWnd;
    IXMessageListener* pListener;
};
typedef std::vector<ListenerInfo> MessageListenerVector;
typedef std::map<UINT, MessageListenerVector>   MessageListenerContainer;

typedef std::vector<IXMessageListener*> MessageFilterVector;

class CXMsgListenSrvImpl : public CXBaseObjImpl<IXMsgListenSrv>, public IXTimer
{
    typedef CXBaseObjImpl<IXMsgListenSrv> superclass;
    DEF_SKIN_CLASS_SINGLE_INTF(CXMsgListenSrvImpl,
        superclass,
        gs_strGuidXSkin,
        IXMsgListenSrv,
        eIntf_Singleton);

public:
    CXMsgListenSrvImpl();
    virtual ~CXMsgListenSrvImpl();

public:
    // IXMsgListenSrv
    virtual HRESULT STDMETHODCALLTYPE AddMessageListener(UINT message, IXMessageListener* pListener);
    virtual HRESULT STDMETHODCALLTYPE DelMessageListener(UINT message, IXMessageListener* pListener);

    virtual HRESULT STDMETHODCALLTYPE AddMessageListener(XWND xWnd, UINT message, IXMessageListener* pListener);
    virtual HRESULT STDMETHODCALLTYPE DelMessageListener(XWND xWnd, UINT message, IXMessageListener* pListener);

    virtual HRESULT STDMETHODCALLTYPE AddMessageFilter(IXMessageListener* pFilter);
    virtual HRESULT STDMETHODCALLTYPE DelMessageFilter(IXMessageListener* pFilter);

    virtual LRESULT STDMETHODCALLTYPE InvokeMessageFilter(XWND xWnd, UINT message, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
    virtual LRESULT STDMETHODCALLTYPE InvokeMessageListener(XWND xWnd, UINT message, WPARAM wParam, LPARAM lParam, BOOL& bHandled);

public:
    // IXBaseObj
    virtual void    STDMETHODCALLTYPE OnFinalRelease();

public:
    // IXTimer
    virtual void STDMETHODCALLTYPE   OnTimer(UINT_PTR uTimerId, void* pData);

protected:
    void        ReleaseData();
    void        NeedCacheTimer();

    BOOL        IsListenerValid(XWND xWnd, UINT message, IXMessageListener* pListener);
    BOOL        IsFilterValid(IXMessageListener* pFilter);

    HRESULT     AddMessageListenerImpl(XWND xWnd, UINT message, IXMessageListener* pListener, BOOL bFilter);
    HRESULT     DelMessageListenerImpl(XWND xWnd, UINT message, IXMessageListener* pListener, BOOL bFilter);

protected:
    MessageListenerContainer    m_MsgListenerCont;
    MessageFilterVector         m_MessageFilter;

    int             m_nInvokeLevel;
    UINT_PTR        m_uCacheTimerId;
    struct stCacheData
    {
        BOOL bFilter;
        BOOL bAdd;
        XWND xWnd;
        UINT message;
        IXMessageListener* pListener;
    };
    typedef std::vector<stCacheData> CacheDataVector;
    CacheDataVector m_vctCacheData;
};

